import { loadShaderFromFile } from '../lib/tool-utils.js';
import * as twgl from '../lib/twgl-full.module.js';
const main = async () => {
  const vs = await loadShaderFromFile('./shader/cube.vert');
  const fs = await loadShaderFromFile('./shader/cube.frag');
  const m4 = twgl.m4;
  const gl = document.querySelector('#c').getContext('webgl');

  const programInfo = twgl.createProgramInfo(gl, [vs, fs]);

  const arrays = {
    // 正方体顶点
    position: [
      1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1,
      -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1,
      -1, 1, -1, -1, -1, -1, -1,
    ],
    // 法向量
    normal: [
      1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,
      -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1,
    ],
    // 纹理坐标
    texcoord: [
      1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1,
      1, 1, 1, 0, 0, 0, 0, 1, 1, 1,
    ],
    // 三角形绘制顺序
    indices: [
      0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21,
      22, 20, 22, 23,
    ],
  };
  const bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);

  // 纹理创建
  const tex = twgl.createTexture(gl, {
    min: gl.NEAREST,
    mag: gl.NEAREST,
    src: [255, 255, 255, 255, 192, 192, 192, 255, 192, 192, 192, 255, 255, 255, 255, 255],
  });

  const uniforms = {
    u_lightWorldPos: [1, 8, -10], // 光照的位置
    u_lightColor: [1, 0.8, 0.8, 1],
    u_ambient: [0, 0, 0, 1], // 周围的
    u_specular: [1, 1, 1, 1], // 镜面反射
    u_shininess: 50, // 光泽度
    u_specularFactor: 1, // 镜面反射系数
    u_diffuse: tex,
  };

  function render(time) {
    time *= 0.001;
    twgl.resizeCanvasToDisplaySize(gl.canvas);
    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

    gl.enable(gl.DEPTH_TEST);
    gl.enable(gl.CULL_FACE);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    const fov = (30 * Math.PI) / 180; // 30度
    const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
    const zNear = 0.5; //轴0.5-10可见
    const zFar = 10;
    // 投影矩阵和四个参数有关，1. 视锥体角度，2.投影平面的宽高比，3. 近处距离，4.远处距离
    const projection = m4.perspective(fov, aspect, zNear, zFar);

    // 相机矩阵和三个参数有关 1. 相机的坐标，2. 看向点的坐标，3. 相机向上坐标
    const eye = [1, 2, -6];
    const target = [0, 0, 0];
    const up = [0, 1, 0];
    const camera = m4.lookAt(eye, target, up);

    // 视图矩阵是相机矩阵的逆，可以理解成将物体移动到相机前（相机不动）
    const view = m4.inverse(camera);
    const viewProjection = m4.multiply(projection, view);
    const world = m4.rotationY(time);

    // 光照计算需要
    uniforms.u_viewInverse = camera;
    uniforms.u_world = world;
    uniforms.u_worldInverseTranspose = m4.transpose(m4.inverse(world));

    // 物体展示和旋转需要
    uniforms.u_worldViewProjection = m4.multiply(viewProjection, world);

    gl.useProgram(programInfo.program);
    twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
    twgl.setUniforms(programInfo, uniforms);
    gl.drawElements(gl.TRIANGLES, bufferInfo.numElements, gl.UNSIGNED_SHORT, 0);

    requestAnimationFrame(render);
  }
  requestAnimationFrame(render);
};
main();
